<template>
  <!-- 大容器 -->
  <div class="com-container">
    <!-- 标题 -->
    <h3 class="title">标签</h3>
    <!-- 图表 -->
    <div class="com-chart" ref="tag_ref">
      <!-- 使用 v-for 指令循环渲染 randerList 数组中的每个 tag 对象 -->
      <!-- 每个 tag 对象代表一个标签，并且通过 :key 绑定唯一的 id 来确保高效更新 -->
      <div
        class="tag"
        v-for="tag in randerList"
        :key="tag.id"
        :style="{
          left: tag.x + 'px',
          top: tag.y + 'px',
          color: tag.color,
          opacity: tag.opacity,
          filter: tag.filter,
          fontSize: tag.fontSize + 'px',
          transform: tag.transform,
        }"
      >
        {{ tag.name }}
      </div>
    </div>
  </div>
</template>

<script>
import { tagChart } from "@/api/cms/charts";
export default {
  // 定义组件的数据属性
  data() {
    return {
      // 存储获取到的标签数据
      tagList: [],
      // 存储经过处理的标签数据
      randerList: [],
      // 球体半径
      radius: 112,
      // 焦距
      distance: 187,
    };
  },
  // 在组件创建完后执行
  created() {
    this.getData();
  },
  // 当组件挂载到DOM上后调用的方法
  mounted() {
    // 监听窗口大小变化事件，并调整图表大小
    window.addEventListener("resize", this.screenAdapter);
  },

  screenAdapter() {
    this.chartInstance.resize();
  },
  methods: {
// 比较函数，用于根据对象的指定属性长度进行排序
    compare(property) {
      return function (a, b) {
        let value1 = a[property].length;
        let value2 = b[property].length;
        return value2 - value1;
      };
    },
    // 获取数据
    async getData() {
      tagChart().then((response) => {
        // 将返回的标签数据赋值给tagList
        this.tagList = response.tag;
        // 初始化标签的位置
        this.initPosition();
      });
    },
    // 生成tag的三维坐标
    initPosition() {
      let len = this.tagList.length;
      let radius = this.radius; //球体半径
      for (let i = 0; i < len; i++) {
        let k = (2 * (i + 1) - 1) / len - 1;
        let a = Math.acos(k);
        let b = a * Math.sqrt(len * Math.PI);
        let x = radius * Math.sin(a) * Math.cos(b);
        let y = radius * Math.sin(a) * Math.sin(b);
        let z = radius * Math.cos(a);
        let fontSize = 12;
        let color =
          "rgb(" +
          parseInt(Math.random() * 255) +
          "," +
          parseInt(Math.random() * 255) +
          "," +
          parseInt(Math.random() * 255) +
          ")";
        let alpha = (z + radius) / (2 * radius);
        let opacity = alpha + 0.5;
        let filter = "alpha(opacity = " + (alpha + 0.5) * 100 + ")";
        this.randerList = this.randerList.concat({
          name: this.tagList[i],
          x: x,
          y: y,
          z: z,
          color: color,
          opacity: opacity,
          filter: filter,
          fontSize: fontSize,
        });
      }
      this.animate();
    },
    // 动画方法
    animate() {
      this.randerList.forEach(function (item) {
        let distance = 187;
        let radius = 112;
        let scale = distance / (distance - item.z);
        let alpha = (item.z + radius) / (2 * radius);
        let transform = "translate(-50%,-50%) scale(" + scale + ")";
        item.opacity = alpha + 0.5;
        item.zIndex = parseInt(scale * 100);
        item.transform = transform;
        item.webkitTransform = transform;
      });
      this.rotateX();
      this.rotateY();
      // console.log(this.randerList)
      requestAnimationFrame(this.animate);
    },
// 围绕X轴旋转标签
    rotateX() {
      let angleX = Math.PI / 500;
      let cos = Math.cos(angleX);
      let sin = Math.sin(angleX);
      this.randerList.forEach(function (item) {
        let y1 = item.y * cos - item.z * sin;
        let z1 = item.z * cos + item.y * sin;
        item.y = y1;
        item.z = z1;
      });
    },
    // 围绕Y轴旋转标签
    rotateY() {
      let angleY = Math.PI / 500;
      let cos = Math.cos(angleY);
      let sin = Math.sin(angleY);
      this.randerList.forEach(function (item) {
        let x1 = item.x * cos - item.z * sin;
        let z1 = item.z * cos + item.x * sin;
        item.x = x1;
        item.z = z1;
      });
    },
  },
};
</script>

<style scoped>
.com-container {
  width: 100%;
  height: 500px;
  position: relative;
}

.com-chart {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: 100%;
}

.tag {
  position: absolute;
}

.tag:hover {
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 5px;
}

.title {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  color: rgba(0, 0, 0, 0.45);
  font-size: 16px;
  font-weight: bold;
}

canvas {
  border-radius: 20px;
}
</style>
